package com.cwrl.spider.common.mq.config;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.annotation.scanner.MethodAnnotationScanner;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.reflect.MethodHandleUtil;
import cn.hutool.core.util.*;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.cwrl.spider.common.mq.annotaion.SpiderMqListener;
import com.cwrl.spider.common.mq.core.ISpiderMqListener;
import com.cwrl.spider.common.mq.core.SpiderMqTemplate;
import com.cwrl.spider.common.mq.domain.SpiderMqMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import javax.annotation.PostConstruct;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.*;

/**
 * 基于Redis实现的mq 默认使用的
 */

@ConditionalOnProperty(
        name = {"spring.spider.mq.type"},
        havingValue = "redis",
        matchIfMissing = false
)
@RequiredArgsConstructor
@Slf4j
public class RedisMqConfiguration  {

//    private final Map<String, ISpiderMqListener<?>> listenerMap;
//
//    private final ApplicationContext applicationContext;

    private final RedisTemplate<String, Object> redisTemplate;

    private final RedisConnectionFactory connectionFactory;

    @Bean
//    @ConditionalOnClass({RedisConnectionFactory.class, RedisTemplate.class})
//    @ConditionalOnBean(RedisTemplate.class)
    public SpiderMqTemplate spiderMqRedisTemplate() {
        return new SpiderMqTemplate() {
            @Override
            public <T> void send(String topic, T message) {
                SpiderMqMessage<?> mqMessage = SpiderMqMessage.builder()
                        .messageId(IdUtil.getSnowflakeNextIdStr())
                        .time(System.currentTimeMillis())
                        .message(message)
                        .build();
                redisTemplate.convertAndSend(topic, mqMessage);
            }

            @Override
            public <T> void sendByBroadcast(String topic, T message) {
                SpiderMqMessage<?> mqMessage = SpiderMqMessage.builder()
                        .messageId(IdUtil.getSnowflakeNextIdStr())
                        .time(System.currentTimeMillis())
                        .message(message)
                        .broadcast(true)
                        .build();
                redisTemplate.convertAndSend(topic, mqMessage);
            }
        };
    }

    @Bean
    public RedisMessageListenerContainer spiderContainer() {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        // 设置连接工厂，RedisConnectionFactory 可以直接从容器中取，也可以从 RedisTemplate 中取
        container.setConnectionFactory(connectionFactory);
        return container;
    }

//    @PostConstruct
//    public void init() {
//        String[] beanNames = applicationContext.getBeanDefinitionNames();
//        for (String beanName : beanNames) {
//            if (StrUtil.equals(beanName, "redisMqConfiguration")) {
//                continue;
//            }
//            Object bean = applicationContext.getBean(beanName);
//            Method[] methods = bean.getClass().getMethods();
//            for (Method method: methods) {
//                boolean annotationPresent = method.isAnnotationPresent(SpiderMqListener.class);
//                if (annotationPresent) {
//                    SpiderMqListener methodAnnotation = method.getAnnotation(SpiderMqListener.class);
//                    List<ChannelTopic> methodTopicList = new ArrayList<>();
//                    for (String topic: methodAnnotation.topic()) {
//                        redisTemplate.opsForList().leftPop(topic);
//                    }
//
//                }
//            }
//        }
//
//    }

}
